package com.moon.springbootinit.pattern;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.moon.springbootinit.common.ErrorCode;
import com.moon.springbootinit.datasource.*;
import com.moon.springbootinit.exception.BusinessException;
import com.moon.springbootinit.exception.ThrowUtils;
import com.moon.springbootinit.model.dto.post.PostQueryRequest;
import com.moon.springbootinit.model.dto.user.UserQueryRequest;
import com.moon.springbootinit.model.entity.Picture;
import com.moon.springbootinit.model.enums.SearchTypeEnum;
import com.moon.springbootinit.model.search.SearchRequest;
import com.moon.springbootinit.model.vo.PostVO;
import com.moon.springbootinit.model.vo.SearchVO;
import com.moon.springbootinit.model.vo.UserVO;
import com.moon.springbootinit.service.PictureService;
import com.moon.springbootinit.service.PostService;
import com.moon.springbootinit.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * 设计模式
 */
@Component
@Slf4j
public class SearchFacade {
    @Resource
    private PictureService pictureService;

    @Resource
    private PostService postService;

    @Resource
    private UserService userService;

    @Resource
    private UserDataSource userDataSource;

    @Resource
    private PostDataSource postDataSource;

    @Resource
    private PictureDataSource pictureDataSource;

    @Resource
    private DataSourceRegistry dataSourceRegistry;

    /**
     * 门面模式
     * @param searchrequest
     * @param request
     * @return
     */
    public SearchVO searchAll03(@RequestBody SearchRequest searchrequest, HttpServletRequest request) {
        //获取搜索类型
        String type = searchrequest.getType();
        //根据搜索类型获取枚举
        SearchTypeEnum searchTypeEnum = SearchTypeEnum.getEnumByValue(type);
        //抛出参数错误
        ThrowUtils.throwIf(StringUtils.isBlank(type),ErrorCode.PARAMS_ERROR);
        //获取搜索文本
        String searchText = searchrequest.getSearchText();
        //搜索出所有数据
        if (searchTypeEnum==null) {
            //异步查询图片
            CompletableFuture<Page<Picture>> pictureTask = CompletableFuture.supplyAsync(() -> {
                //根据搜索文本和分页信息查询图片
                Page<Picture> picturePage = pictureService.searchPicture(searchText, 1, 10);
                return picturePage;
            });

            //异步查询帖子
            CompletableFuture<Page<PostVO>> postTask = CompletableFuture.supplyAsync(() -> {
                //根据搜索文本和分页信息查询帖子
                PostQueryRequest postQueryRequest = new PostQueryRequest();
                postQueryRequest.setSearchText(searchText);
                Page<PostVO> postVOPage = postService.listPostVOByPage(postQueryRequest, request);
                return postVOPage;
            });

            //异步查询用户
            CompletableFuture<Page<UserVO>> userTask = CompletableFuture.supplyAsync(() -> {
                //根据搜索文本和分页信息查询用户
                UserQueryRequest userQueryRequest = new UserQueryRequest();
                userQueryRequest.setUserName(searchText);
                Page<UserVO> userVOPage = userService.listUserVOByPage(userQueryRequest);
                return userVOPage;
            });

            //等待所有异步任务完成
            CompletableFuture.allOf(pictureTask, postTask, userTask).join();

            try {
                //获取查询结果
                Page<Picture> picturePage = pictureTask.get();
                Page<PostVO> postVOPage = postTask.get();
                Page<UserVO> userVOPage = userTask.get();

                //封装查询结果
                SearchVO searchVO = new SearchVO();
                searchVO.setPictureList(picturePage.getRecords());
                searchVO.setPostList(postVOPage.getRecords());
                searchVO.setUserList(userVOPage.getRecords());
                return searchVO;
            } catch (Exception e) {
                log.error("search error", e);
                throw new BusinessException(ErrorCode.SYSTEM_ERROR,"查询异常");
            }
        }else {
            //封装查询结果
            SearchVO searchVO = new SearchVO();
            switch (searchTypeEnum){

                case USER:
                    //根据搜索文本和分页信息查询用户
                    UserQueryRequest userQueryRequest = new UserQueryRequest();
                    userQueryRequest.setUserName(searchText);
                    Page<UserVO> userVOPage = userService.listUserVOByPage(userQueryRequest);
                    searchVO.setUserList(userVOPage.getRecords());
                    break;
                case POST:
                    //根据搜索文本和分页信息查询帖子
                    PostQueryRequest postQueryRequest = new PostQueryRequest();
                    postQueryRequest.setSearchText(searchText);
                    Page<PostVO> postVOPage = postService.listPostVOByPage(postQueryRequest, request);
                    searchVO.setPostList(postVOPage.getRecords());
                    break;
                case PICTURE:
                    //根据搜索文本和分页信息查询图片
                    Page<Picture> picturePage = pictureService.searchPicture(searchText, 1, 10);
                    searchVO.setPictureList(picturePage.getRecords());
                    break;
                default:
            }
            return searchVO;
        }
    }

    /**
     * 适配器模式
     * 通过适配器模式统一参数
     * @param searchrequest
     * @param request
     * @return
     */
    public SearchVO searchAll04(@RequestBody SearchRequest searchrequest, HttpServletRequest request) {
        String type = searchrequest.getType();
        long current = searchrequest.getCurrent();
        long pageSize = searchrequest.getPageSize();
        SearchTypeEnum searchTypeEnum = SearchTypeEnum.getEnumByValue(type);
        ThrowUtils.throwIf(StringUtils.isBlank(type),ErrorCode.PARAMS_ERROR);
        String searchText = searchrequest.getSearchText();
        //搜索出所有数据
        if (searchTypeEnum==null) {
            CompletableFuture<Page<Picture>> pictureTask = CompletableFuture.supplyAsync(() -> {
                Page<Picture> picturePage = pictureDataSource.doSearch(searchText, 1, 10);
                return picturePage;
            });

            CompletableFuture<Page<PostVO>> postTask = CompletableFuture.supplyAsync(() -> {
                PostQueryRequest postQueryRequest = new PostQueryRequest();
                postQueryRequest.setSearchText(searchText);
                Page<PostVO> postVOPage = postDataSource.doSearch(searchText, current,pageSize);
                return postVOPage;
            });

            CompletableFuture<Page<UserVO>> userTask = CompletableFuture.supplyAsync(() -> {
                UserQueryRequest userQueryRequest = new UserQueryRequest();
                userQueryRequest.setUserName(searchText);
                Page<UserVO> userVOPage = userDataSource.doSearch(searchText,current,pageSize);
                return userVOPage;
            });

            CompletableFuture.allOf(userTask,postTask,pictureTask).join();

            try {
                Page<UserVO> userVOPage = userTask.get();
                Page<PostVO> postVOPage = postTask.get();
                Page<Picture> picturePage = pictureTask.get();
                SearchVO searchVO = new SearchVO();
                searchVO.setUserList(userVOPage.getRecords());
                searchVO.setPostList(postVOPage.getRecords());
                searchVO.setPictureList(picturePage.getRecords());
                return searchVO;
            } catch (Exception e) {
                log.error("search error", e);
                throw new BusinessException(ErrorCode.SYSTEM_ERROR,"查询异常");
            }
        }else {
            //我们把所有的数据都放到map中
            Map<String, DataSource<T>> dataSourceMap = new HashMap(){{
                put(SearchTypeEnum.POST.getValue(),pictureDataSource);
                put(SearchTypeEnum.USER.getValue(),postDataSource);
                put(SearchTypeEnum.PICTURE.getValue(),userDataSource);
            }};
            DataSource<T> dataSource = dataSourceMap.get(type);
            Page<?> page = dataSource.doSearch(searchText, current, pageSize);
            SearchVO searchVO = new SearchVO();
            searchVO.setDataList(page.getRecords());
            return searchVO;
        }
    }

    /**
     * 注册器模式
     * 提前通过一个map或者其他类型存储好后面需要调用的对象
     * @param searchrequest
     * @param request
     * @return
     */
    public SearchVO searchAll05(@RequestBody SearchRequest searchrequest, HttpServletRequest request) {
        String type = searchrequest.getType();
        long current = searchrequest.getCurrent();
        long pageSize = searchrequest.getPageSize();
        SearchTypeEnum searchTypeEnum = SearchTypeEnum.getEnumByValue(type);
        ThrowUtils.throwIf(StringUtils.isBlank(type),ErrorCode.PARAMS_ERROR);
        String searchText = searchrequest.getSearchText();
        //搜索出所有数据
        if (searchTypeEnum==null) {
            CompletableFuture<Page<Picture>> pictureTask = CompletableFuture.supplyAsync(() -> {
                Page<Picture> picturePage = pictureDataSource.doSearch(searchText, 1, 10);
                return picturePage;
            });

            CompletableFuture<Page<PostVO>> postTask = CompletableFuture.supplyAsync(() -> {
                PostQueryRequest postQueryRequest = new PostQueryRequest();
                postQueryRequest.setSearchText(searchText);
                Page<PostVO> postVOPage = postDataSource.doSearch(searchText, current,pageSize);
                return postVOPage;
            });

            CompletableFuture<Page<UserVO>> userTask = CompletableFuture.supplyAsync(() -> {
                UserQueryRequest userQueryRequest = new UserQueryRequest();
                userQueryRequest.setUserName(searchText);
                Page<UserVO> userVOPage = userDataSource.doSearch(searchText,current,pageSize);
                return userVOPage;
            });

            CompletableFuture.allOf(userTask,postTask,pictureTask).join();

            try {
                Page<UserVO> userVOPage = userTask.get();
                Page<PostVO> postVOPage = postTask.get();
                Page<Picture> picturePage = pictureTask.get();
                SearchVO searchVO = new SearchVO();
                searchVO.setUserList(userVOPage.getRecords());
                searchVO.setPostList(postVOPage.getRecords());
                searchVO.setPictureList(picturePage.getRecords());
                return searchVO;
            } catch (Exception e) {
                log.error("search error", e);
                throw new BusinessException(ErrorCode.SYSTEM_ERROR,"查询异常");
            }
        }else {
            //注册器模式关键代码
            DataSource<?> dataSource = dataSourceRegistry.getDataSourceByType(type);
            Page<?> page = dataSource.doSearch(searchText, current, pageSize);
            SearchVO searchVO = new SearchVO();
            searchVO.setDataList(page.getRecords());
            return searchVO;
        }
    }
}
